using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

namespace BeeldBank.Toolkit
{
    public class DigitalInfo
    {
        #region StripGarbage
        private string StripGarbage(string tmpStr)
        {
            tmpStr = tmpStr.Replace(".\r\n", ".<br />");
            tmpStr = tmpStr.Replace("\r\n-", "<br />-");
            tmpStr = tmpStr.Replace("\r\n", " ");
            tmpStr = tmpStr.Replace("Demo;", "");
            tmpStr = tmpStr.Replace("DemoDemo", "Demo");
            tmpStr = tmpStr.Replace("DemoDem", "");
            tmpStr = tmpStr.Replace("DemoDe", "");
            tmpStr = tmpStr.Replace("DemoD", "");
            tmpStr = tmpStr.Replace("Demo", "");
            tmpStr = tmpStr.Replace("  ", " ");
            tmpStr = tmpStr.Replace("N57; N57;", "N57;");
            tmpStr = tmpStr.Replace("JAcobapolder", "Jacobapolder;");
            tmpStr = tmpStr.Replace("Walcheren; Walcheren;", "Walcheren;");
            tmpStr = tmpStr.Replace("luchtfoto; luchtfoto;", "luchtfoto;");
            tmpStr = tmpStr.Replace("luchtfoto; luchtfoto;", "luchtfoto;");
            tmpStr = tmpStr.Replace("luchtfoto; luchtfoto;", "luchtfoto;");
            tmpStr = tmpStr.Replace("luchtfoto; luchtfoto;", "luchtfoto;");
            tmpStr = tmpStr.Replace("foto: Joop van Houdt Luchtfotografie/Rijkswatersta at", "");
            tmpStr = tmpStr.Replace("Foto: Rijkswaterstaat / Joop van Houdt", "");
            tmpStr = tmpStr.Replace("foto: Rijkswaterstaat / Joop van Houdt", "");
            tmpStr = tmpStr.Replace("foto: Rijkswaterstaat / Joop van HOudt", "");
            tmpStr = tmpStr.Replace("Foto Rijkswaterstaat / Joop van Houdt", "");
            tmpStr = tmpStr.Replace("Foto: Joop van Houdt / Rijkswatertsaat", "");
            tmpStr = tmpStr.Replace("Foto: Joop van Houdt / Rijkswaterstaat", "");
            tmpStr = tmpStr.Replace("foto: Joop van Houdt Luchtfotografie", "");
            tmpStr = tmpStr.Replace("foto: Joop van Houdt luchtfotografie", "");
            tmpStr = tmpStr.Replace("foto: Joop van Houdt / Rijkswaterstaat", "");
            tmpStr = tmpStr.Replace("foto: Joop van Houdt . Rijkswaterstaat", "");
            tmpStr = tmpStr.Replace("foto: Joop van Houdt/Rijkswaterstaat", "");
            
            tmpStr = tmpStr.Replace("Foto: Joop van Houdt", "");
            tmpStr = tmpStr.Replace("foto: Joop van Houdt", "");
            tmpStr = tmpStr.Replace("Joop van Houdt fotografie", "");
            tmpStr = tmpStr.Replace("Joop van Houdt", "");
            
            tmpStr = tmpStr.Replace("Foto:Ton Poortvliet/HH", "");
            tmpStr = tmpStr.Replace("Foto:HSL-Zuid/Ton Poortvliet", "");
            return tmpStr.Trim();
        }
        #endregion

        #region PartialReturnString
        private string ReturnToEndString(string StartText)
        {
            string tmpStr = "";
            int StartOfText = this.StrippedText.IndexOf(StartText) + StartText.Length;
            if (StartOfText < StartText.Length)
            {
                // Niets gevonden
            }
            else
            {
                try
                {
                    tmpStr = this.StrippedText.Substring(StartOfText).Trim();
                }
                catch
                {
                }
            }
            return StripGarbage(tmpStr);
        }

        private string PartialReturnString(string StartText, string EndText)
        {
            string tmpStr = "";
            int StartOfText = this.StrippedText.IndexOf(StartText) + StartText.Length;
            if (StartOfText < StartText.Length)
            {
                // Niets gevonden
            }
            else
            {
                int LengthOfText = this.StrippedText.IndexOf(EndText) - StartOfText;
                try
                {
                    int RealStartOfText = this.StrippedText.IndexOf(": ", StartOfText) + 2;
                    tmpStr = this.StrippedText.Substring(RealStartOfText, LengthOfText - (RealStartOfText - StartOfText)).Trim();
                }
                catch
                {
                }
            }
            return StripGarbage(tmpStr);
        }

        private string PartialReturnString(string StartText, string EndText, string EndText2)
        {
            string tmpStr = "";
            int StartOfText = this.StrippedText.IndexOf(StartText) + StartText.Length;
            if (StartOfText < StartText.Length)
            {
                // Niets gevonden
            }
            else
            {
                int LengthOfText = 0;
                int LengthOfText1 = this.StrippedText.IndexOf(EndText) - StartOfText;
                int LengthOfText2 = this.StrippedText.IndexOf(EndText2) - StartOfText;
                if ((LengthOfText1 > LengthOfText2) && (LengthOfText1 > 0) && (LengthOfText2 > 0))
                    LengthOfText = LengthOfText2;
                else
                    if (LengthOfText1 < 0)
                        LengthOfText = LengthOfText2;
                    else
                        LengthOfText = LengthOfText1;
                try
                {
                    int RealStartOfText = this.StrippedText.IndexOf(": ", StartOfText) + 2;
                    tmpStr = this.StrippedText.Substring(RealStartOfText, LengthOfText - (RealStartOfText - StartOfText)).Trim();
                }
                catch
                {
                    // Let's assume that it is the end of the file after the keywords
                    LengthOfText1 = this.StrippedText.IndexOf("\r\n") - StartOfText;
                    try
                    {
                        tmpStr = this.StrippedText.Substring(StartOfText).Trim();
                        if (tmpStr.Length > 30)
                            tmpStr = "";
                    }
                    catch
                    {
                    }
                }
            }
            return StripGarbage(tmpStr);
        }
        #endregion

        #region DateOfRealisation
        public string DateOfRealisation
        {
            get
            {
                string returnString = "";
                int i = 1;
                while ((returnString == "") && (i < 8))
                {
                    switch (i)
                    {
                        case 1:
                            // GPS Date (if present)
                            returnString = TryToFindDate("Datestamp", "Differential Correction", "IPTC ", returnString);
                            break;
                        case 2:
                        // Image creation date
                            returnString = TryToFindDate("Date/Time Taken", "Date/Time Digitised", "", returnString);
                            break;
                        case 3:
                            returnString = TryToFindDate("CreateDate", "XMP ", returnString);
                            break;
                        case 4:
                            returnString = TryToFindDate("CreateDate", "ModifyDate", returnString);
                            break;
                        case 5:
                            returnString = TryToFindDate("Creation Date", "Originating Program", "Byline", returnString);
                            break;
                        case 6:
                            returnString = TryToFindDate("Date/Time Modified", "Artist", "YCbCr Positioning", returnString);
                            break;
                        case 7:
                            try
                                {
                                    returnString = this.Description.Substring(this.Description.IndexOf(",") + 1, this.Description.IndexOf(".") - this.Description.IndexOf(","));
                                    returnString = returnString.Substring(returnString.IndexOf(",") + 1, returnString.IndexOf(".") - returnString.IndexOf(",") - 1);
                                    DateTime dt = DateTime.Parse(returnString, new CultureInfo("nl-NL"));
                                }
                                catch
                                {
                                    try
                                    {
                                        returnString = ReturnToEndString("Date/Time Taken");
                                        string stringYear = returnString.Substring(0, 4);
                                        string stringMonth = returnString.Substring(5, 2);
                                        string stringDay = returnString.Substring(8, 2);
                                        returnString = stringDay + "-" + stringMonth + "-" + stringYear;
                                        DateTime dt = DateTime.Parse(returnString, new CultureInfo("nl-NL"));
                                    }
                                    catch
                                    {
                                        return defaultDate;
                                    }
                                }

                            break;
                    }
                    i++;
                }
                return returnString.Substring(0, 10);
            }
        }

        private string TryToFindDate(string input1, string input2, string returnString)
        {
            try
            {
                returnString = PartialReturnString(input1, input2).Trim();
                DateTime dt = DateTime.Parse(returnString.Substring(0, 10), new CultureInfo("en-US"));
            }
            catch
            {
                try
                {
                    string stringYear = returnString.Substring(0, 4);
                    string stringMonth = returnString.Substring(5, 2);
                    string stringDay = returnString.Substring(8, 2);
                    returnString = stringDay + "-" + stringMonth + "-" + stringYear;
                    DateTime dt = DateTime.Parse(returnString, new CultureInfo("nl-NL"));
                }
                catch
                {
                    returnString = "";
                }
            }
            return returnString;
        }

        private string TryToFindDate(string input1, string input2, string input3, string returnString)
        {
            try
            {
                returnString = PartialReturnString(input1, input2, input3).Trim();
                DateTime dt = DateTime.Parse(returnString.Substring(0, 10), new CultureInfo("en-US"));
            }
            catch
            {
                try
                {
                    string stringYear = returnString.Substring(0, 4);
                    string stringMonth = returnString.Substring(5, 2);
                    string stringDay = returnString.Substring(8, 2);
                    returnString = stringDay + "-" + stringMonth + "-" + stringYear;
                    DateTime dt = DateTime.Parse(returnString, new CultureInfo("nl-NL"));
                }
                catch
                {
                    returnString = "";
                }
            }
            return returnString;
        }
        #endregion

        #region Title
        public string Title
        {
            get
            {
                string tmpString = "";
                try
                {
                    tmpString = PartialReturnString("Description", "Make", "Strip Offset").Trim();

                    if (TitelFilterStart == "Filename") tmpString = "";

                    if (tmpString.Length == 0)
                    {
                        tmpString = PartialReturnString("XP Title", "XP Comment", "XP Author").Trim();
                        if (tmpString.Length == 0)
                        {
                            tmpString = PartialReturnString("XP Title", "XP Author", "XP Keywords").Trim();
                            if (tmpString.Length == 0)
                            {
                                /* Dan maar de filenaam */
                                tmpString = this.fileName.Substring(this.fileName.LastIndexOf("\\", this.fileName.Length));
                                tmpString = tmpString.Substring(1, tmpString.LastIndexOf(".") - 1);
                            }
                        }
                    }
                }
                catch
                {
                }
                finally
                {
                    if (tmpString.Length == 0)
                    {
                        /* Dan maar de filenaam */
                        tmpString = this.fileName.Substring(this.fileName.LastIndexOf("\\", this.fileName.Length));
                        tmpString = tmpString.Substring(1, tmpString.LastIndexOf(".") - 1);
                    }
                }

                if ((TitelFilterStart != "") && (TitelFilterEnd != ""))
                {
                    int firstPos = tmpString.IndexOf(TitelFilterStart);
                    if (firstPos == 0)
                    {
                    }
                    else
                    {
                        int secondPos = tmpString.IndexOf(TitelFilterEnd, firstPos + 1);
                        if (secondPos == 0)
                        {
                            // Return vanaf de eerste punt
                            tmpString = tmpString.Substring(firstPos, tmpString.Length).Trim();
                        }
                        else
                        {
                            // Return tussen eerste en tweede punt
                            if (secondPos > 0)
                                tmpString = tmpString.Substring(firstPos + 1, secondPos - firstPos - 1).Trim();
                        }
                    }
                }

                return tmpString;
            }
        }
        #endregion

        #region Description
        public string Description
        {
            get
            {
                string tmpString = "";
                try
                {
                    tmpString = PartialReturnString("Description", "Make", "Strip Offset").Trim();
                    if (tmpString.Length == 0)
                    {
                        tmpString = PartialReturnString("Caption", "Photoshop\r\n");
                        if (tmpString.Length == 0)
                        {
                            tmpString = PartialReturnString("XP Title", "XP Comment", "XP Author").Trim();
                            if (tmpString.Length == 0)
                            {
                                tmpString = PartialReturnString("XP Title", "Image  ").Trim();
                                if (tmpString.Length == 0)
                                {
                                    tmpString = PartialReturnString("XP Subject", "Custom Render", "Image  ").Trim();
                                    if (tmpString.Length == 0)
                                    {
                                        /* Dan maar de filenaam */
                                        tmpString = this.fileName.Substring(this.fileName.LastIndexOf("\\", this.fileName.Length));
                                        tmpString = tmpString.Substring(1, tmpString.LastIndexOf(".") - 1);
                                    }
                                }
                            }
                        }
                    }
                }
                catch
                {
                }
                return tmpString + Keywords;
            }
        }
        #endregion

        #region Keywords
        public string Keywords
        {
            get
            {
                string tmpString = "";
                bool Ready = false;
                try
                {
                    tmpString = PartialReturnString("XP Keywords ", "XP Subject").Trim();
                    if (tmpString.Length != 0)
                        tmpString = "<br />Trefwoorden: " + tmpString;
                    else
                    {
                        tmpString = PartialReturnString("Keywords", "Creation Date", "Photoshop\r\n").Trim();
                        if ((tmpString.Length == 0) || (tmpString.Contains("Byline")) || (tmpString.Contains("Copyright")) || (tmpString.Contains("Caption")) || (tmpString.Contains("Special Instructions")))
                        {
                            if (tmpString.Contains("Copyright") || tmpString.Contains("Caption"))
                            {
                                tmpString = PartialReturnString("Keywords", "Copyright Notice", "Caption").Trim();
                                if (tmpString.Length != 0)
                                {
                                    if (tmpString.Contains("Caption") || tmpString.Contains("Byline") || tmpString.Contains("Creation Date") || tmpString.Contains("Byline Title"))
                                        Ready = false;
                                    else
                                    {
                                        tmpString = "<br />Trefwoorden: " + tmpString;
                                        Ready = true;
                                    }
                                }

                                if (!Ready)
                                {
                                    if (tmpString.Contains("Caption") || tmpString.Contains("Byline") || tmpString.Contains("Byline Title"))
                                    {
                                        tmpString = PartialReturnString("Keywords", "Byline  ", "Byline Title").Trim();
                                        if (tmpString.Length != 0)
                                            tmpString = "<br />Trefwoorden: " + tmpString;
                                        else
                                        {
                                            tmpString = PartialReturnString("Keywords", "Byline Title", "Caption").Trim();
                                            if (tmpString.Length != 0)
                                                tmpString = "<br />Trefwoorden: " + tmpString;
                                            else
                                            {
                                                tmpString = PartialReturnString("Keywords", "Byline  ", "Caption").Trim();
                                                if (tmpString.Length != 0)
                                                    tmpString = "<br />Trefwoorden: " + tmpString;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        tmpString = PartialReturnString("Keywords", "Creation Date", "Caption").Trim();
                                        if (tmpString.Length != 0)
                                        {
                                            tmpString = "<br />Trefwoorden: " + tmpString;
                                        }
                                    }
                                }
                            }
                        }
                        else
                            tmpString = "<br />Trefwoorden: " + tmpString;
                    }
                }
                catch
                {
                }
                finally
                {
                }
                return tmpString;
            }
        }
        #endregion

        #region Author
        public string Author
        {
            get
            {
                string tmpString = "";
                try
                {
                    tmpString = PartialReturnString("XP Author", "XP Keywords", "XP Subject").Trim();
                    if (tmpString.Length == 0)
                    {
                        tmpString = PartialReturnString("Artist", "Copyright").Trim();
                    }
                }
                catch
                {
                }
                finally
                {
                }
                return tmpString;
            }
        }
        #endregion

        #region Url
        public string Url
        {
            get
            {
                string tmpString = "";
                try
                {
                    if (Latitude.Length != 0)
                    {
                        tmpString = "http://maps.google.com/maps?f=q&hl=nl&z=16&q=" + Latitude.Replace(" ", "%20") + LatitudeRef + "," + Longitude.Replace(" ", "%20") + LongitudeRef;
                        tmpString = "<br /><strong>GPS:</strong> " + Latitude + LatitudeRef + "," + Longitude + LongitudeRef + "<br /><strong>Hoogte:</strong> " + Altitude + "<br /><strong>Tijdstip:</strong> " + Date + " " + Time + "<br /><a title='Externe doorverwijzing naar de lokatie op Google maps' href='" + tmpString + "'><strong>Toon lokatie op Google maps</strong></a>";
                    }
                }
                catch
                {
                }
                return tmpString;
            }
        }
        #endregion

        #region LatitudeRef
        public string LatitudeRef
        {
            get
            {
                string tmpString = PartialReturnString("Latitude Reference", "Latitude  ").Trim();
                if (tmpString.Length != 0)
                {
                    return tmpString.Substring(0, 1);
                }
                else return "";
            }
        }
        #endregion

        #region Latitude
        public string Latitude
        {
            get
            {
                string tmpString = PartialReturnString("Latitude  ", "Longitude Reference").Trim();
                if (tmpString.Length != 0)
                {
                    return tmpString;
                }
                else return "";
            }
        }
        #endregion

        #region LongitudeRef
        public string LongitudeRef
        {
            get
            {
                string tmpString = PartialReturnString("Longitude Reference", "Longitude  ").Trim();
                if (tmpString.Length != 0)
                {
                    return tmpString.Substring(0, 1);
                }
                else return "";
            }
        }
        #endregion

        #region Longitude
        public string Longitude
        {
            get
            {
                string tmpString = PartialReturnString("Longitude  ", "Altitude Reference", "Time").Trim();
                if (tmpString.Length != 0)
                {
                    return tmpString;
                }
                else return "";
            }
        }
        #endregion

        #region Altitude
        public string Altitude
        {
            get
            {
                string tmpString = PartialReturnString("Altitude  ", "Time  ", "Satellite").Trim();
                if (tmpString.Length != 0)
                {
                    return tmpString;
                }
                else return "";
            }
        }
        #endregion

        #region Time
        public string Time
        {
            get
            {
                string tmpString = PartialReturnString("Time  ", "Satellite  ", "Geodetic Survey Data").Trim();
                if (tmpString.Length == 0)
                {
                    tmpString = PartialReturnString("Time  ", "Geodetic Survey Data").Trim();
                        
                    if (tmpString.Length != 0)
                    {
                        return tmpString;
                    }
                    else return "";
                }
                return tmpString;
            }
        }
        #endregion

        #region Date
        public string Date
        {
            get
            {
                string tmpString = PartialReturnString("Datestamp", "IPTC ", "\r\nPhotoshop").Trim();
                if (tmpString.Length == 0)
                {
                    tmpString = PartialReturnString("Datestamp", "Differential Correction", "IPTC ").Trim();
                    if (tmpString.Length != 0)
                    {
                        return tmpString;
                    }
                    else return "";
                }
                return tmpString;
            }
        }
        #endregion

        private string _fileName = "";
        public string fileName
        {
            get
            {
                return _fileName;
            }
            set
            {
                _fileName = value;
                readFile();
            }
        }
        private string _defaultDate = "";
        public string defaultDate
        {
            get
            {
                return _defaultDate;
            }
            set
            {
                _defaultDate = value;
            }
        }
        private string _StartDescription = "";
        public string StartDescription
        {
            get
            {
                return _StartDescription;
            }
            set
            {
                _StartDescription = value;
            }
        }
        private string _EndDescription = "";
        public string EndDescription
        {
            get
            {
                return _EndDescription;
            }
            set
            {
                _EndDescription = value;
            }
        }
        private string _EndDescription2 = "";
        public string EndDescription2
        {
            get
            {
                return _EndDescription2;
            }
            set
            {
                _EndDescription2 = value;
            }
        }
        private string _StartTitel = "";
        public string StartTitel
        {
            get
            {
                return _StartTitel;
            }
            set
            {
                _StartTitel = value;
            }
        }
        private string _EndTitel = "";
        public string EndTitel
        {
            get
            {
                return _EndTitel;
            }
            set
            {
                _EndTitel = value;
            }
        }
        private string _TitelFilterStart = "";
        public string TitelFilterStart
        {
            get
            {
                return _TitelFilterStart;
            }
            set
            {
                _TitelFilterStart = value;
            }
        }
        private string _TitelFilterEnd = "";
        public string TitelFilterEnd
        {
            get
            {
                return _TitelFilterEnd;
            }
            set
            {
                _TitelFilterEnd = value;
            }
        }
        private void readFile()
        {
            this._strippedText = System.IO.File.ReadAllText(_fileName);
        }

        public string GetXml()
        {
            string returnString = "";
            returnString += "<xml>";
            returnString += "<description><![CDATA[" + this.Description + "]]></description>";
            returnString += "<titel><![CDATA[" + this.Title + "]]></titel>";
            returnString += "<datum>" + this.DateOfRealisation + "</datum>";
            returnString += "<trefwoorden><![CDATA[" + this.Keywords + "]]></trefwoorden>";
            returnString += "<vervaardiger><![CDATA[" + this.Author + "]]></vervaardiger>";
            returnString += "<googlelink><![CDATA[" + this.Url + "]]></googlelink>";
            returnString += "<longitude>" + BeeldbankMVCTools.MediaObjectTools.Long_fromString(this.Longitude) + "</longitude>";
            returnString += "<latitude>" + BeeldbankMVCTools.MediaObjectTools.Lat_fromString(this.Latitude) + "</latitude>";
            returnString += "<hoogte>" + BeeldbankMVCTools.MediaObjectTools.Hoogte_fromString(this.Altitude) + "</hoogte>";
            returnString += "</xml>";
            
            return returnString;
        }

        public void SaveXml(string fileLocation)
        {
            System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();

            xmlDoc.LoadXml(this.GetXml());
            xmlDoc.Save(fileLocation);
            xmlDoc = null;
        }

        private string _strippedText = "";
        public string StrippedText
        {
            get
            {
                return _strippedText;
            }
        }
        public DigitalInfo()
        {
        }
    }
}
